package com.zcsy.commons.sms.dlife;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* 类名称：XmlUtils   
* 类描述：   xml操作工具类   查询xml节点等
* 创建人：qiuju   
* 创建时间：2013-11-6 下午03:18:23     
* @version
 */
public class XmlUtils {

	 /** 
     * 传入xml 返回xml根节点 
     * @param xml  
     * @return element 
     */  
	public static Element getRootElement(String xml, String enc) {
		Element element = null;
		// documentBuilder为抽象不能直接实例化(将XML文件转换为DOM文件)
		DocumentBuilder db = null;
		DocumentBuilderFactory dbf = null;

		try {
			InputStream is = new ByteArrayInputStream(xml.getBytes(enc));
			// 得到DOM解析器的工厂实例
			// 得到javax.xml.parsers.DocumentBuilderFactory；类的实例就是我们要的解析器工厂
			dbf = DocumentBuilderFactory.newInstance();
			// 从DOM工厂获得DOM解析器
			// 通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder（）得到DOM解析器
			db = dbf.newDocumentBuilder();
			// 得到一个DOM并返回给document对象
			Document dt = db.parse(is);
			// 得到XML文档的根节点
			// 在DOM中只有根节点是一个org.w3c.dom.Element对象。
			element = dt.getDocumentElement();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		return element;
	}
	
	  /** 
     * 传入父节点fatherNode，返回所有子节点childNode放入ArrayList中 
     * @param element 
     * @return ArrayList 
     */  
    public static ArrayList<Node> getAllChildNodes(NodeList fatherNode){  
        ArrayList<Node> al = new ArrayList<Node>();  
        //遍历所有节点  
        for (int i = 0; i < fatherNode.getLength(); i++){  
            Node childNode = fatherNode.item(i);  
            //如果子节点为空跳过  
            if("#text".equals(childNode.getNodeName())){  
                continue;  
            }  
            //子节点有内容，加入到arraylist中  
            al.add(childNode);  
        }  
        return al;  
    } 
    
    /** 
     * 传入父节点fatherNode，返回所有子节点childNode放入ArrayList中 
     * @param element 
     * @return ArrayList 
     */  
    public static ArrayList<Node> getAllChildNodes(Node fatherNode){  
        ArrayList<Node> al = new ArrayList<Node>();  
        //遍历所有节点  
        NodeList nodeList = fatherNode.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++){  
            Node childNode = nodeList.item(i);  
            //如果子节点为空跳过  
            if("#text".equals(childNode.getNodeName())){  
                continue;  
            }  
            //子节点有内容，加入到arraylist中  
            al.add(childNode);  
        }  
        return al;  
    } 
    
    /** 
     * 传入父节点fatherNode，和字符串name，返回子节点名字等于name的childNode放入ArrayList中 
     * @param element 
     * @param name 
     * @return ArrayList 
     */  
    public static ArrayList<Node> getChildNodesByName(NodeList fatherNode,String name){  
        ArrayList<Node> al = new ArrayList<Node>();  
        //遍历所有节点  
        for (int i = 0; i < fatherNode.getLength(); i++){  
            Node childNode = fatherNode.item(i);  
            //如果子节点的名字等于name  
            if(name.equals(childNode.getNodeName())){  
                //加入到arraylist中  
                al.add(childNode);  
            }  
        }  
        return al;  
    }  
    
    /** 
     * 传入父节点fatherNode，和字符串name，返回子节点名字等于name的childNode放入ArrayList中 
     * @param element 
     * @param name 
     * @return ArrayList 
     */  
    public static ArrayList<Node> getChildNodesByName(Node fatherNode,String name){  
        ArrayList<Node> al = new ArrayList<Node>();  
        //遍历所有节点  
        NodeList nodeList = fatherNode.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++){  
            Node childNode = nodeList.item(i);  
            //如果子节点的名字等于name  
            if(name.equals(childNode.getNodeName())){  
                //加入到arraylist中  
                al.add(childNode);  
            }  
        }  
        return al;  
    } 
    
    /**
     * 查找父节点下的子节点并转换为map
     * @param fatherNode
     * @return
     */
    public static Map<String, String> getChildNodesByMap(Node fatherNode) {
    	List<Node> childNodes = getAllChildNodes(fatherNode);
    	if (!childNodes.isEmpty()) {
    		Map<String, String> map = new HashMap<String, String>();
    		for (Node node : childNodes) {
    			String name = getElementName(node);
    			String value = getElementValue(node);
    			map.put(name, value);
    		}
    		return map;
    	} else {
    		return null;
    	}
    }
    
    /** 
     * 传入父节点fatherNode，和字符串name，返回子节点名字等于name的childNode放入ArrayList中 
     * @param element 
     * @param name 
     * @return ArrayList 
     */  
    public static Node getChildNodeByName(Node fatherNode,String name){  
        //遍历所有节点  
        NodeList nodeList = fatherNode.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++){  
            Node childNode = nodeList.item(i);  
            //如果子节点的名字等于name  
            if(name.equals(childNode.getNodeName())){  
                return childNode;  
            }  
        }  
        return null;  
    } 
    
    /** 
     * 传入父节点fatherNode，和字符串name，返回子节点属性attributes等于name的childNode放入ArrayList中 
     * @param fatherNode 
     * @param attributes 
     * @param name 
     * @return 
     */  
    public static ArrayList<Node> getChildNodesAttributes(NodeList fatherNode,String attributes,String name){  
        ArrayList<Node> al = new ArrayList<Node>();  
        //遍历所有节点  
        for (int i = 0; i < fatherNode.getLength(); i++){  
            Node childNode = fatherNode.item(i);  
            try {  
                //如果子节点的属性attributes等于name，则加入到arraylist中  
                if(name.equals(childNode.getAttributes().getNamedItem(attributes).getNodeValue())){  
                    al.add(childNode);  
                }  
            } catch (NullPointerException e) {  
                // TODO: handle exception  
                //System.out.println("该节点没有属性");  
            }  
        }  
        return al;  
    }  
    
    /**
     * 方法名称：getElementName<p>
     * 方法功能：获取指定Element的名称            <p>
     * 参数说明：@param element
     * 参数说明：@return <p>
     * 返回：String <p>
     **/
	public static String getElementName(Node element) {
		return element.getNodeName();
	}
	
	 /**
	   * 方法名称：getElementValue<p>
	   * 方法功能：获取指定Element的值<p>
	   * 参数说明：@param element
	   * 参数说明：@return <p>
	 **/
	public static String getElementValue(Node element) {
		NodeList nl = element.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			if (nl.item(i).getNodeType() == Node.TEXT_NODE) {// 是一个Text Node
				return element.getFirstChild().getNodeValue();
			}
		}
		return null;
	}
	
	/**
	 * 方法名称：getElementAttr
	 * <p>
	 * 方法功能：获取指定Element的属性attr的值
	 * <p>
	 * 参数说明：@param element 参数说明：@param attr 参数说明：@return
	 **/
	public static String getElementAttr(Element element, String attr) {
		return element.getAttribute(attr);
	}
	
	/**
	 * 方法名称：setElementValue
	 * <p>
	 * 方法功能：设置指定Element的值
	 * <p>
	 * 参数说明：@param element 参数说明：@param val
	 * <p>
	 **/
	public static void setElementValue(Element element, String val) {
		Node node = element.getOwnerDocument().createTextNode(val);
		NodeList nl = element.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node nd = nl.item(i);
			if (nd.getNodeType() == Node.TEXT_NODE)// 是一个Text Node
			{
				nd.setNodeValue(val);
				return;
			}
		}
		element.appendChild(node);
	}
	
	/**
	 * 方法名称：setElementAttr
	 * <p>
	 * 方法功能：设置结点Element的属性
	 * <p>
	 * 参数说明：@param element 参数说明：@param attr 参数说明：@param attrVal
	 * <p>
	 * 返回：void
	 * <p>
	 **/
	public static void setElementAttr(Element element, String attr,
			String attrVal) {
		element.setAttribute(attr, attrVal);
	}

	/**
	 * 方法名称：addElement
	 * <p>
	 * 方法功能：在parent下增加结点child
	 * <p>
	 * 参数说明：@param parent 参数说明：@param child
	 * <p>
	 * 返回：void
	 * <p>
	 **/
	public static void addElement(Element parent, Element child) {
		parent.appendChild(child);
	}

	/**
	 * 方法名称：addElement
	 * <p>
	 * 方法功能：在parent下增加字符串tagName生成的结点
	 * <p>
	 * 参数说明：@param parent 参数说明：@param tagName
	 * <p>
	 * 返回：void
	 * <p>
	 **/
	public static void addElement(Element parent, String tagName) {
		Document doc = parent.getOwnerDocument();
		Element child = doc.createElement(tagName);
		parent.appendChild(child);
	}

	/**
	 * 方法名称：addElement
	 * <p>
	 * 方法功能：在parent下增加tagName的Text结点，且值为text
	 * <p>
	 * 参数说明：@param parent 参数说明：@param tagName 参数说明：@param text
	 * <p>
	 * 返回：void
	 * <p>
	 **/
	public static void addElement(Element parent, String tagName, String text) {
		Document doc = parent.getOwnerDocument();
		Element child = doc.createElement(tagName);
		setElementValue(child, text);
		parent.appendChild(child);
	}

	/**
	 * 方法名称：removeElement
	 * <p>
	 * 方法功能：将父结点parent下的名称为tagName的结点移除
	 * <p>
	 * 参数说明：@param parent 参数说明：@param tagName
	 * <p>
	 * 返回：void
	 * <p>
	 **/
	public static void removeElement(Element parent, String tagName) {
		NodeList nl = parent.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node nd = nl.item(i);
			if (nd.getNodeName().equals(tagName)) {
				parent.removeChild(nd);
			}
		}
	}
	
	
	private static String createRootNode(String className) {
		int ind = className.lastIndexOf('.');
		String tmp = className.substring(ind + 1);
		
		return tmp.substring(0, 1).toLowerCase() + tmp.substring(1);
	}
	
	private static String createNode(String methodName) {
		String tmp = methodName.substring(3);
		
		return tmp.substring(0, 1).toLowerCase() + tmp.substring(1);
	}
	
	/**
	 * Just for String as the parameter
	 */
	public static String convertObjToXml(Object obj) {
		Class<?> clazz = obj.getClass();
		Method[] methods = clazz.getMethods();
		
		StringBuffer xml = new StringBuffer();
		String root = createRootNode(clazz.getName());
		xml.append("<" + root + ">");
		String methodName = "";
		for (Method method : methods) {
			methodName = method.getName();
			if (methodName.startsWith("get") && method.getReturnType().equals(String.class)) {
				xml.append("<" + createNode(methodName) + ">");
				try {
					xml.append((String) method.invoke(obj));
				} catch (Exception e) {
					// Nothing to do
				}
				xml.append("</" + createNode(methodName) + ">");
			}
		}
		xml.append("</" + root + ">");
		
		return xml.toString();
	}
	
	
	
	public static void main(String args[]) {
//	    String xml="<?xml version=\"1.0\" encoding=\"utf-8\"?><response><infoquery><merchantid>97180</merchantid><action>product</action></infoquery><queryresult><resultcode>0</resultcode><resultdescription>查询成功</resultdescription></queryresult><productlists><productlist><productid>3897</productid><productname>MYCARD450点卡可充卡巴拉岛/AIKA/台服剑侠等450不可充台服战网</productname><parvalue>100.00</parvalue><purchase>94.000</purchase><inventorynumber>0</inventorynumber></productlist></productlists></response>";
	    String xml="<?xml version=\"1.0\" encoding=\"utf-8\"?><response><infoquery><merchantid>97180</merchantid><action>product</action></infoquery><queryresult><resultcode>0</resultcode><resultdescription>查询|成功</resultdescription></queryresult><productlists><productlist id=\"123\"><productid>3897</productid><productname>MYCARD450\"点\"卡|可充卡巴拉岛/AIKA/台服剑侠等|不可充台服战网</productname><parvalue>100.00</parvalue><purchase>94.000</purchase><inventorynumber>0</inventorynumber></productlist></productlists></response>";
	    xml = xml.replaceAll("\\|", "\u007C");
	    Element rootElement = getRootElement(xml,"utf-8");
	    Node queryResultNode = XmlUtils.getChildNodeByName(rootElement, "queryresult");
		Node resultCodeNode = XmlUtils.getChildNodeByName(queryResultNode, "resultcode");
		String resultcode = XmlUtils.getElementValue(resultCodeNode);
		Node resultdescriptionNode = XmlUtils.getChildNodeByName(queryResultNode, "resultdescription");
		
		String resultdescription = XmlUtils.getElementValue(resultdescriptionNode);
		String[] aa = resultdescription.split("\\|");
		for (String a : aa) {
			System.out.println(a);
		}
		
		
		System.out.println("resultcode:"+ resultcode);
		Node productlistsNode =  XmlUtils.getChildNodeByName(rootElement, "productlists");
		List<Node> productlistNodeList = XmlUtils.getChildNodesByName(productlistsNode, "productlist");//商品列表
		List<Map<String, String>> productList = new ArrayList<Map<String,String>>();
		for (Node product : productlistNodeList) {
			String id = XmlUtils.getElementAttr((Element)product, "id");
			System.out.println(id);
			Map<String, String> productMap = XmlUtils.getChildNodesByMap(product);
			String name = productMap.get("productname");
//			name = name.replaceAll("u007C", "\\|");
//			productMap.put("productname", name);
			productList.add(productMap);
		}
		System.out.println(productList.size());
		System.out.println("a\u0022.length()+\u0022b".length()); 
		System.out.println("\u007C");
	}
    
}
